package cz.pecinovsky.english.pojj.adv_demo.byt_lednička;

import cz.pecinovsky.english.pojj.adv_framework.game_txt.IGame;
import cz.pecinovsky.english.pojj.adv_framework.game_txt.ICommand;

import cz.pecinovsky.english.pojj.adv_framework.scenario.AScenarioManager;


import java.util.Collection;



/*******************************************************************************
 * Instance třídy {@code Hra_BytLednička} představují hru, při níž se hráč ocitne
 * v malém bytě, který je třeba projít a najít v něm ledničku.
 * Mají na starosti logiku hry.
 * Jsou schopny akceptovat jednotlivé příkazy a poskytovat informace
 * o průběžném stavu hry a jejích součástech.
 *
 * @author    Rudolf PECINOVSKÝ
 * @version   5.0
 */
public class Hra_BytLednička implements IGame
{
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================

    /** Zda bude používán spráce scénářů s konstantami nebo literály. */
    private static final boolean SPRÁVCE_S_KONSTANTAMI = false;

    /** Aktuálně provozovaná hra. Je-li tento odkaz prázdný, není aktuálně
     *  provozována žádná hra a může se spustit nová. */
    private static Hra_BytLednička aktuálníHra = new Hra_BytLednička();



//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================
//== STATICKÝ INICIALIZAČNÍ BLOK - STATICKÝ KONSTRUKTOR ========================
//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================

    /** Správce scénářů, s jejichž pomocí je možno hru testovat
     * nebo domonstrovat její možný průběh. */
    private final AScenarioManager správceScénářů =
                            (SPRÁVCE_S_KONSTANTAMI  ?  new SprávceKonstanta()
                                                    :  new SprávceLiterál  () );



//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================
//== PŘÍSTUPOVÉ METODY ATRIBUTŮ TŘÍDY ==========================================

    /***************************************************************************
     * Vrátí odkaz na aktuálně provozovanou instanci hry.
     * Metoda slouží k tomu, aby mohli někžteré metody získat odkaz
     * na aktuální hru a od ní pak získat jinak nedostupné informace.
     *
     * @return Požadovaný odkaz
     */
    public static Hra_BytLednička getHra()
    {
        return aktuálníHra;
    }



//== OSTATNÍ NESOUKROMÉ METODY TŘÍDY ===========================================

//##############################################################################
//== KONSTRUKTORY A TOVÁRNÍ METODY =============================================

    /***************************************************************************
     * Vytvoří novou hru a nastaví jí správce scénářů.
     */
    private Hra_BytLednička()
    {
        Hra_BytLednička já = this;
        správceScénářů.setGame(já);
    }



//== ABSTRAKTNÍ METODY =========================================================
//== PŘÍSTUPOVÉ METODY INSTANCÍ ================================================

    /***************************************************************************
     * Vrátí jméno autora scénáře ve formátu "PŘÍJMENÍ Křestní",
     * tj. neprve příjmení psané velkými písmeny a za ním křestní jméno,
     * u nějž bude velké pouze první písmeno a ostatní písmena budou malá.
     *
     * @return Jméno autora/autorky programu ve tvaru PŘÍJMENÍ Křestní
     */
    @Override
    public String getAuthor()
    {
        return správceScénářů.getAuthor();
    }


    /***************************************************************************
     * Vrátí x-name autora/autorky programu zapsané velkými písmeny.<p>
     *
     * @return X-name autora/autorky programu
     */
    @Override
    public String getXNAME()
    {
        return správceScénářů.getXNAME();
    }


    /***************************************************************************
     * Vrátí odkaz na aktuální místnost,
     * tj. na místnost, v niž se pravé nachází hráč.
     *
     * @return Požadovaný odkaz
     */
    @Override
    public Místnost getActualPlace()
    {
        return Místnost.getAktuálníMístnost();
    }


    /***************************************************************************
     * Vrátí odkaz na batoh, do nějž bude hráč ukládat sebrané předměty.
     *
     * @return Požadovaný odkaz
     */
    @Override
    public Batoh getBag()
    {
        return Batoh.getBatoh();
    }


    /***************************************************************************
     * Vrátí kolekci odkazů na jednotlivé místnosti.
     *
     * @return Požadovaná kolekce
     */
    @Override
    public Collection<Místnost> getAllPlaces()
    {
        return Místnost.getMístnosti();
    }


    /***************************************************************************
     * Vrátí kolekci všech příkazů použitelných ve hře.
     *
     * @return Požadovaná kolekce
     */
    @Override
    public Collection<ICommand> getAllCommands()
    {
        return APříkaz.getPříkazy();
    }


    /***************************************************************************
     * Vrátí informaci o tom, je-li hra již ukončena.
     *
     * @return Požadovaná informace
     */
    @Override
    public boolean isReady()
    {
        return APříkaz.isSkončeno();
    }


    /***************************************************************************
     * Vrátí správce scénářů, které umožní prověřit funkčnost hry
     * a/nebo demonstrovat její průběh.
     *
     * @return Správce scénářů dané hry
     */
    @Override
    public AScenarioManager getScenarioManager()
    {
        return správceScénářů;
    }

//
//    /***************************************************************************
//     * Vrátí zadanou verzi scénáře, který prověří správnou funkčnost hry.
//     * Každá hra musí mít scénář s indexem 0.
//     * Scénáře s dalšími indexy se vytvářejí na požádání.
//     *
//     * @param index Pořadové číslo požadovaného scénáře.
//     * @return Požadovaný scénář
//     */
//    @Override
//    public IScénář getScenario( int index )
//    {
//        return new XPECR999_Pecinovsky(index);
//    }
//

    /***************************************************************************
     * Ukončí celou hru a vrátí alokované prostředky.
     */
    @Override
    public void stop()
    {
        APříkaz.konec();
    }


    /***************************************************************************
     * Zpracuje zadaný příkaz a vrátí text zprávy pro uživatele.
     *
     * @param prikaz Zadávaný příkaz
     * @return Textová odpověď hry na zadaný příkaz
     */
    @Override
    public String executeCommand( String prikaz )
    {
        return APříkaz.zpracujPříkaz(prikaz);
    }



//+++ Přidáno pro rozšířené zadnání v předmětu 4IT115 ++++++++++++++++++++++++++
//
//    /***************************************************************************
//     * Vrati vstupni znakovy proud obsahujici napovedu.
//     *
//     * @return Pozadovany odkaz
//     */
//    @Override
//    public URL getHelpURL()
//    {
//        throw new UnsupportedOperationException("Prozatím neimplementováno");
//    }
//
//
//    /***************************************************************************
//     * Vrati obrazek s plankem prostoru, v nemz se hraje.
//     *
//     * @return Pozadovnay obrazek
//     */
//    @Override
//    public ImageIcon getPlánek()
//    {
//        throw new UnsupportedOperationException("Prozatím neimplementováno");
//    }
//
//
//    /***************************************************************************
//     * Vrati odkaz na prepravku s názvy prikazu pro presun do jine mistnosti,
//     * zvednutí předmětu a jeho položení.
//     *
//     * @return Pozadovany odkaz
//     */
//    @Override
//    public Prikazy getZakladniPrikazy()
//    {
//        return prikazy;
//    }
//
//
//    /***************************************************************************
//     * Přidá zadaného posluchače do seznamu posluchačů,
//     * které zpravuje o změně množiny předmětů v batohu.
//     *
//     * @param posluchac Přihlašovaný posluchač
//     */
//    @Override
//    public void prihlasPosluchaceBatohu(IPosluchač<IBatoh> posluchac)
//    {
//        batoh.prihlasPosluchace(posluchac);
//    }
//
//
//    /***************************************************************************
//     * Odebere zadaného posluchače ze seznamu posluchačů,
//     * které zpravuje o změně množiny předmětů v batohu.
//     *
//     * @param posluchac Odhlašovaný posluchač
//     */
//    @Override
//    public void odhlasPosluchaceBatohu(IPosluchač<IBatoh> posluchac)
//    {
//        batoh.odhlasPosluchace(posluchac);
//    }
//
//
//    /***************************************************************************
//     * Přidá zadaného posluchače do seznamu posluchačů,
//     * které zpravuje o změně množiny předmětů v aktuální místnosti.
//     *
//     * @param posluchac Přihlašovaný posluchač
//     */
//    @Override
//    public void prihlasPosluchacePremetu(IPosluchač<IMístnost> posluchac)
//    {
//        Místnost.prihlasPosluchacePremetu(posluchac);
//    }
//
//
//    /***************************************************************************
//     * Odebere zadaného posluchače ze seznamu posluchačů,
//     * které zpravuje o změně množiny předmětů v aktuální místnosti.
//     *
//     * @param posluchac Odhlašovaný posluchač
//     */
//    @Override
//    public void odhlasPosluchacePremetu(IPosluchač<IMístnost> posluchac)
//    {
//        Místnost.odhlasPosluchacePremetu(posluchac);
//    }
//
//
//    /***************************************************************************
//     * Přidá zadaného posluchače do seznamu posluchačů,
//     * které zpravuje o změně množiny sousedů aktuální místnosti.
//     *
//     * @param posluchac Přihlašovaný posluchač
//     */
//    @Override
//    public void prihlasPosluchaceSousedu(IPosluchač<IMístnost> posluchac)
//    {
//        Místnost.prihlasPosluchaceSousedu(posluchac);
//    }
//
//
//    /***************************************************************************
//     * Odebere zadaného posluchače ze seznamu posluchačů,
//     * které zpravuje o změně množiny sousedů aktuální místnosti.
//     *
//     * @param posluchac Odhlašovaný posluchač
//     */
//    @Override
//    public void odhlasPosluchaceSousedu(IPosluchač<IMístnost> posluchac)
//    {
//        Místnost.odhlasPosluchaceSousedu(posluchac);
//    }
//
//
//    /***************************************************************************
//     * Přidá zadaného posluchače do seznamu posluchačů,
//     * kterým hra oznamuje začátek a konec rozhovoru.
//     *
//     * @param posluchac Přihlašovaný posluchač
//     */
//    @Override
//    public void prihlasPosluchaceRozhovoru(IPosluchač<Boolean> posluchac)
//    {
//        APříkaz.prihlasPosluchaceRozhovoru(posluchac);
//    }
//
//
//    /***************************************************************************
//     * Odebere zadaného posluchače ze seznamu posluchačů,
//     * kterým hra oznamuje začátek a konec rozhovoru.
//     *
//     * @param posluchac Odhlašovaný posluchač
//     */
//    @Override
//    public void odhlasPosluchaceRozhovoru(IPosluchač<Boolean> posluchac)
//    {
//        APříkaz.odhlasPosluchaceRozhovoru(posluchac);
//    }
//
//
//
//== OSTATNÍ NESOUKROMÉ  METODY INSTANCÍ =======================================
//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================
//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================
//== VNOŘENÉ A VNITŘNÍ TŘÍDY ===================================================
//== TESTOVACÍ METODY A TŘÍDY ==================================================
//
//     /***************************************************************************
//      * Testovací metoda.
//      */
//     public static void test()
//     {
//        Hra_BytLednička hra = getHra();
//        _Test_101 test = _Test_101.getInstance(hra);
//        test.testGame();
//     }
//     /** @param args Parametry příkazového řádku - nepoužité. */
//     public static void main( String... args ) { test(); }
}
